﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Collections;
using System.Text.RegularExpressions;
using System.Xml.XPath;
using System.Web;

namespace HtmlAgilityPack
{
    public partial class HtmlDocument : IXPathNavigable
    {
        /// <summary>
        /// Get content of a forum by xpath function /text()
        /// </summary>
        /// <returns></returns>
        public string GetContentText()
        {
            string content = "";
            string xpath = ".//*[not(self::style) and not(self::script) and not(self::a)]/text()";
            foreach (HtmlNode node in this.DocumentNode.SelectNodes(xpath))
            {
                string textHtml = node.InnerHtml;
                if (string.IsNullOrEmpty(textHtml)) continue;
                //Loại bỏ những đoạn text có chứa các con số (như là ngày tháng, số liệu thống kế views, replies,...)
                string pattern = @"\d+";
                Regex r = new Regex(pattern);
                Match m = r.Match(textHtml);
                if (!m.Success)
                    content += textHtml + ". ";
            }
            return TokenizeSentence(content);
        }

        /// <summary>
        /// Tokenize một câu thành các word cụ thể
        /// </summary>
        /// <param name="sentence"></param>
        /// <returns></returns>
        public string TokenizeSentence(string sentence)
        {
            //Đoạn code này dùng để loại bỏ các ký tự đặc biệt (Giống như tokenize nhưng có loại bỏ ký tự đặc biệt)
            //======================================================================================================
            //Regex r = new Regex();
            sentence = Regex.Replace(sentence, "([\\t{}():;._,\\-! \"?\n&|]|<(/|)form>)", " ");
            sentence = Regex.Replace(sentence, "\\s+", " ");
            //Normalize_Casing(ref sentence);
            sentence = sentence.ToLower();
            string[] tokens = sentence.Split(new char[] { ' ' });
            ArrayList filter = new ArrayList();

            for (int i = 0; i < tokens.Length; i++)
            {
                //MatchCollection mc = r.Matches(tokens[i]);
                //if (mc.Count <= 0 && tokens[i].Trim().Length > 0)
                //{
                //Kiểm tra xem mảng chứa token này chưa
                if (!filter.Contains(tokens[i]))
                    filter.Add(tokens[i]);
                //}
            }
            //Concat into a string and return result
            sentence = string.Join(" ", (string[])filter.ToArray(typeof(string)));

            return sentence;
        }

        /// <summary>
        /// Get hidden value by name
        /// </summary>
        /// <param name="type"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public string GetValueInInputTag(string type, string keyName, string keyValue)
        {
            string value = "";
            try
            {
                string pattern = string.Format(".//input[@type='{0}' and @{1}='{2}']", type, keyName, keyValue);
                HtmlNode node = this.DocumentNode.SelectSingleNode(pattern);
                if (node != null)
                    value = node.Attributes["value"].Value;
            }
            catch
            {

            }
            return value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="forumUrl"></param>
        /// <param name="blackListUrl"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetAllLinks(string forumUrl, string blackListUrl)
        {
            Dictionary<string, string> links = new Dictionary<string, string>();
            string url = "", title = "";
            HtmlNodeCollection nc = this.DocumentNode.SelectNodes(".//a");
            if (nc == null)
                return links;

            Regex r = new Regex(blackListUrl);
            //get all links in forum if xpath not found
            foreach (HtmlNode link in nc)
            {
                foreach (HtmlNode node in link.ChildNodes)
                {
                    if (node.Name == "strong" || node.Name == "#text" || node.Name == "span")
                    {
                        url = System.Web.HttpUtility.UrlDecode(link.Attributes["href"].Value);
                        title = System.Web.HttpUtility.HtmlDecode(node.InnerHtml);
                        //Kiểm tra xem nội dung bên trong node có empty không
                        if (!string.IsNullOrEmpty(url) &&
                            !string.IsNullOrEmpty(title))
                        {
                            if (!string.IsNullOrEmpty(blackListUrl))
                            {
                                //check url contains blaclist?
                                Match m = r.Match(url.ToLower());
                                if (!m.Success)
                                {
                                    //If contains url not is forumUrl then ignore
                                    if (url.Contains("http://") &&
                                        !url.Contains(GetName(forumUrl)))
                                        continue;

                                    if (!links.ContainsKey(url))
                                        links.Add(url, title);
                                }
                            }
                            else
                            {
                                if (!links.ContainsKey(url))
                                    links.Add(url, title);
                            }

                        }
                    }
                }
            }
            return links;
        }

        ///<summary>
        /// Get name of a website from url string
        ///</summary>
        ///<param name="url"></param>
        ///<returns></returns>
        public static string GetName(string url)
        {
            //string pattern = @"(?<=http://)(www.|)(?<value>.*)(?=\.)";
            string pattern = @"(?<=http(s|)://)(www.|)(?<value>[0-9a-zA-Z]*)(?=\.)";

            Regex r = new Regex(pattern);
            Match m = r.Match(url);
            string forumname = "";
            if (m.Success)
            {
                forumname = m.Result("${value}");
            }
            return forumname;
        }

        /// <summary>
        /// Get value by regex pattern
        /// </summary>
        /// <param name="pattern"></param>
        public string GetValueByRegexPattern(string pattern)
        {
            string value = "";
            try
            {
                Regex r = new Regex(pattern);
                Match m = r.Match(this.DocumentNode.InnerHtml);
                if (m.Success)
                    value = m.Result("${value}");
            }
            catch
            {
            }
            return value;
        }
    }

    //public class ForumHtmlDocument : HtmlDocument
    //{
    //     <summary>
    //     Return result in two key "type" and "forumtype" of Dictionary
    //     </summary>
    //     <param name="doc"></param>
    //     <returns></returns>
    //    public Dictionary<string, string> GetForumType(CookieCollection cookieColl)
    //    {
    //        Dictionary<string, string> list = new Dictionary<string, string>();
    //        list.Add("type", "*Unknown*");
    //        list.Add("version", "");
    //        string htmlContent = System.Web.HttpUtility.HtmlEncode(doc.DocumentNode.InnerHtml.ToLower());
    //        string htmlContent = doc.DocumentNode.InnerHtml.ToLower();
    //        *****************************************************************
    //        Search phpBB3
    //        *****************************************************************
    //        string pattern = @"ucp\.php\?mode\=(login|register|logout)";
    //        Regex r = new Regex(pattern);
    //        Match m = r.Match(htmlContent);
    //        if (m.Success)
    //        {
    //            list["type"] = "phpbb3";
    //            list["version"] = "3";
    //        }

    //        *****************************************************************
    //        Search phpBB2
    //        *****************************************************************
    //        if (list["type"] == "*Unknown*")
    //        {
    //            pattern = @"profile\.php\?mode\=(register|editprofile)";
    //            r = new Regex(pattern);
    //            m = r.Match(htmlContent);
    //            if (m.Success)
    //            {
    //                list["type"] = "phpbb2";
    //                list["version"] = "2";
    //            }
    //        }

    //        *****************************************************************
    //        Search ipBoard
    //        *****************************************************************
    //        if (list["type"] == "*Unknown*")
    //        {
    //            pattern = @"app\=core\&amp\;(amp\;|)module\=global\&amp\;(amp\;|)section\=(login|register|login\&amp\;(amp\;|)do\=logout)";
    //            pattern = @"app\=core\&module\=global\&section\=(login|register)";
    //            r = new Regex(pattern);
    //            m = r.Match(htmlContent);
    //            if (m.Success)
    //            {
    //                Get Version
    //                pattern = @"ipbv\=(?<version>([0-9]+))";
    //                pattern = @"(?<type>ip(\.|)board)(</a>|)\s*(?<version>([0-9]\.[0-9]\.[0-9]|))";
    //                r = new Regex(pattern);
    //                m = r.Match(htmlContent);
    //                if (m.Success)
    //                {
    //                    if (!string.IsNullOrEmpty(m.Result("${version}").ToString()))
    //                    {
    //                        list["version"] = m.Result("${version}").ToString();
    //                        if (list["version"].Contains("31"))
    //                            list["type"] = "IPB31x";
    //                        else if (list["version"].Contains("32"))
    //                            list["type"] = "IPB32x";
    //                    }
    //                }
    //                else
    //                {
    //                    list["type"] = "IPB";
    //                }
    //            }
    //        }

    //        ******************************************************************************
    //        Search vBulletin 
    //        ******************************************************************************
    //        if (list["type"] == "*Unknown*")
    //        {
    //            First, find patterns as "vbulletin x.x.x"
    //            pattern = @"vbulletin(\&\#8482\;|\&reg\;|\&trade\;|)(</a>|)\s*(version|)\s*((?<version>([0-9]\.[0-9]\.[0-9]))|)";
    //            pattern = @"vbulletin";
    //            if (htmlContent.Contains(pattern))
    //            {
    //                if (cookieColl["bblastactivity"] != null)
    //                    list["type"] = "vBulletin3x";
    //                else if (cookieColl["bb_lastactivity"] != null)
    //                    list["type"] = "vBulletin4x";
    //                else
    //                    list["type"] = "vBulletin";

    //                pattern = @"vbulletin.*(version|)\s*(?<version>([0-9]+\.[0-9]+\.[0-9]+))";
    //                r = new Regex(pattern);
    //                m = r.Match(htmlContent);
    //                if (m.Success)
    //                {
    //                    Search forum type again
    //                    if (!string.IsNullOrEmpty(m.Result("${version}").ToString()))
    //                    {
    //                        list["version"] = m.Result("${version}").ToString();
    //                        if (list["type"] == "*Unknown*" || list["type"] == "vBulletin")
    //                        {
    //                            if (list["version"][0].ToString() == "3")
    //                                list["type"] = "vBulletin3x";
    //                            else if (list["version"][0].ToString() == "4")
    //                                list["type"] = "vBulletin4x";
    //                        }
    //                    }
    //                }
    //            }
    //        }
    //        return list;
    //    }
    //}
}
